<template>
  <div class="chat-container">
    <!-- 页面头部 -->
    <div class="page-header">
      <h3>
        AI 智能助手
        <span v-if="currentSession" class="session-info">
          - {{ truncateTitle(currentSession.title, 15) }}
        </span>
      </h3>
      <div class="header-actions" @click.stop>
        <el-select
          v-if="sessions.length > 1"
          v-model="currentSessionId"
          placeholder="选择会话"
          style="width: 200px; margin-right: 8px"
          size="default"
        >
          <el-option
            v-for="session in sessions"
            :key="session.session_id"
            :label="truncateTitle(session.title, 25)"
            :value="session.session_id"
          />
        </el-select>

        <el-button-group>
          <!-- <el-button
            @click="toggleSystemEdit"
            :type="showSystemEdit ? 'primary' : 'default'"
            size="default"
          >
            <SvgIcon name="user-edit" size="16px" />
            <span style="margin-left: 6px">角色管理</span>
          </el-button> -->
          <el-button @click="startNewChat" type="success" size="default">
            <SvgIcon name="add" size="16px" />
            <span style="margin-left: 6px">新对话</span>
          </el-button>
          <el-button
            @click="deleteCurrentSession"
            type="danger"
            size="default"
            :disabled="!currentSession"
            plain
          >
            <SvgIcon name="delete" size="16px" />
            <span style="margin-left: 6px">删除会话</span>
          </el-button>
          <el-button
            @click="exportChat"
            size="default"
            :disabled="messages.length === 0"
          >
            导出对话
          </el-button>
        </el-button-group>
      </div>
    </div>

    <!-- 角色管理悬浮框 -->
    <el-dialog
      v-model="showSystemEdit"
      title="角色管理"
      width="600px"
      :modal="true"
      :close-on-click-modal="false"
      :close-on-press-escape="true"
      class="role-dialog"
    >
      <!-- 角色选择区域 -->
      <div class="role-selection">
        <el-text type="info" size="small" style="margin-bottom: 12px">
          选择角色:
        </el-text>
        <div class="role-tabs">
          <el-tag
            v-for="role in userRoles"
            :key="role.id"
            :type="
              currentRole && currentRole.id === role.id ? 'primary' : 'default'
            "
            :effect="
              currentRole && currentRole.id === role.id ? 'dark' : 'plain'
            "
            class="role-tag"
            @click="selectRole(role)"
            size="large"
          >
            {{ role && role.name ? role.name : '未命名角色' }}
            <el-tag
              v-if="role && role.is_default"
              type="success"
              size="small"
              style="margin-left: 6px"
            >
              默认
            </el-tag>
          </el-tag>
        </div>
      </div>

      <!-- 角色编辑区域 -->
      <div v-if="currentRole && editingRole" class="role-edit">
        <el-form :model="editingRole" label-width="100px" label-position="top">
          <el-form-item label="角色名称">
            <el-input
              v-model="editingRole.name"
              placeholder="输入角色名称..."
              maxlength="20"
              show-word-limit
            />
            <div class="role-checkbox">
              <el-checkbox v-model="editingRole.is_default">
                使用此角色
              </el-checkbox>
            </div>
          </el-form-item>

          <el-form-item label="系统角色设定">
            <div class="template-header">
              <el-select
                v-model="selectedTemplate"
                @change="applyTemplate"
                placeholder="选择预设模板"
                clearable
                style="width: 200px"
                size="small"
              >
                <el-option
                  v-for="template in systemTemplates"
                  :key="template.key"
                  :label="template.name"
                  :value="template.key"
                />
              </el-select>
            </div>
            <el-input
              v-model="editingRole.system_prompt"
              type="textarea"
              placeholder="描述AI助手的角色和行为特征..."
              :rows="4"
            />
          </el-form-item>

          <el-alert
            title="💡 提示: 清晰的角色描述可以让AI更好地理解你的需求和回答风格"
            type="info"
            :closable="false"
            show-icon
            style="margin-bottom: 16px"
          />
        </el-form>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="closeRoleDialog">取消</el-button>
          <el-button @click="resetRoleEdit">
            <SvgIcon name="reload" size="16px" />
            <span style="margin-left: 6px">重置修改</span>
          </el-button>
          <el-button
            type="primary"
            @click="saveCurrentRole"
            :disabled="!hasRoleChanges"
            :loading="saving"
          >
            <SvgIcon name="save" size="16px" />
            <span style="margin-left: 6px">保存角色</span>
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 聊天内容区域 -->
    <el-card class="messages-card" body-style="padding: 0">
      <div class="messages-container" ref="messagesContainer">
        <!-- 欢迎消息 -->
        <div v-if="messages.length === 0" class="welcome-message">
          <div class="welcome-icon">
            <SvgIcon name="robot" size="48px" />
          </div>
          <div class="welcome-text">您好！我是AI智能助手</div>
          <div class="welcome-desc">您可以发送文字或上传图片与我对话</div>
        </div>

        <!-- 消息列表 -->
        <div
          v-for="(message, index) in messages"
          :key="index"
          class="message-item"
          :class="message.role"
        >
          <div class="message-avatar">
            <el-avatar :size="36" v-if="message.role === 'user'">
              <SvgIcon name="user" size="20px" />
            </el-avatar>
            <el-avatar :size="36" v-else>
              <SvgIcon name="robot" size="20px" />
            </el-avatar>
          </div>
          <div class="message-content">
            <div class="message-time">{{ formatTime(message.timestamp) }}</div>
            <div
              v-if="message.type === 'text'"
              class="message-text"
              v-html="formatMessage(message.content || message.text)"
            ></div>
            <div
              v-else-if="message.type === 'multimodal'"
              class="message-multimodal"
            >
              <div
                v-if="message.images && message.images.length > 0"
                class="message-images"
              >
                <el-image
                  v-for="(image, idx) in message.images"
                  :key="idx"
                  :src="image.url"
                  :alt="`图片${idx + 1}`"
                  class="message-image"
                  fit="cover"
                  :preview-src-list="image_urls"
                  :initial-index="image_urls.indexOf(image.url)"
                />
              </div>
              <div
                v-if="message.text && message.text.trim()"
                class="message-text"
                v-html="formatMessage(message.text)"
              ></div>
            </div>
          </div>
        </div>

        <!-- 正在输入指示器 -->
        <div v-if="isTyping" class="message-item assistant typing">
          <div class="message-avatar">
            <el-avatar :size="36">
              <SvgIcon name="robot" size="20px" />
            </el-avatar>
          </div>
          <div class="message-content">
            <div class="typing-indicator">
              <span></span>
              <span></span>
              <span></span>
            </div>
          </div>
        </div>
      </div>
    </el-card>

    <!-- 输入区域 -->
    <el-card class="input-card" body-style="padding: 16px">
      <!-- 图片预览区域 -->
      <div v-if="selectedImages.length > 0" class="image-preview-container">
        <div
          v-for="(image, index) in selectedImages"
          :key="index"
          class="image-preview-item"
        >
          <el-image
            :src="image.url"
            :alt="`预览图片${index + 1}`"
            class="preview-image"
            fit="cover"
          />
          <el-button
            @click="removeImage(index)"
            class="remove-image-btn"
            type="danger"
            size="small"
            circle
            icon="Close"
          />
        </div>
      </div>

      <!-- 富文本工具栏 -->
      <div v-if="isRichTextMode" class="toolbar">
        <el-button-group size="small">
          <el-button @click="insertFormat('**', '**')" title="加粗">
            <strong>B</strong>
          </el-button>
          <el-button @click="insertFormat('*', '*')" title="斜体">
            <em>I</em>
          </el-button>
          <el-button @click="insertFormat('`', '`')" title="代码">
            &lt;/&gt;
          </el-button>
          <el-button @click="insertFormat('```\n', '\n```')" title="代码块">
            [ ]
          </el-button>
        </el-button-group>
        <el-button-group size="small">
          <el-button @click="insertFormat('- ', '')" title="列表">≡</el-button>
          <el-button @click="insertFormat('> ', '')" title="引用">"</el-button>
        </el-button-group>
      </div>

      <!-- 输入框 -->
      <div class="input-wrapper">
        <el-input
          ref="messageInput"
          v-model="currentMessage"
          type="textarea"
          :placeholder="
            isLoading
              ? 'AI正在回复中，您可以继续输入下一个问题...'
              : '输入您的问题...'
          "
          :rows="isRichTextMode ? 4 : 2"
          resize="none"
          @keydown.enter.prevent="handleEnterKey"
          @input="adjustTextareaHeight"
        />

        <!-- 控制按钮 -->
        <div class="input-controls">
          <div class="left-controls">
            <el-button @click="triggerImageUpload" size="small" plain>
              <SvgIcon name="photo" size="16px" />
              <span style="margin-left: 6px">图片</span>
            </el-button>
            <input
              type="file"
              ref="imageInput"
              multiple
              accept="image/*"
              style="display: none"
              @change="handleImageUpload"
            />

            <el-button
              @click="toggleRichTextMode"
              size="small"
              :type="isRichTextMode ? 'primary' : 'default'"
              plain
              title="富文本模式"
            >
              <SvgIcon name="notes" size="16px" />
              <span style="margin-left: 6px">富文本</span>
            </el-button>
          </div>

          <div class="right-controls">
            <el-button
              type="primary"
              @click="sendMessage"
              :disabled="!canSend"
              :loading="isLoading"
              size="default"
            >
              <SvgIcon name="send" size="16px" />
              <span style="margin-left: 6px">发送</span>
            </el-button>
          </div>
        </div>
      </div>
    </el-card>

    <!-- Toast 提示 -->
    <!-- <el-notification
      v-if="toast.show"
      :title="toast.message"
      :type="toast.type"
      position="top-right"
      :duration="3000"
      @close="toast.show = false"
    /> -->
  </div>
</template>

<script>
import SvgIcon from '@/views/components/SvgIcon.vue'
import request from '@/utils/request'
import { marked } from 'marked'

export default {
  name: 'ChatV2',
  components: {
    SvgIcon,
  },
  data() {
    return {
      image_urls: [],
      messages: [],
      currentMessage: '',
      selectedImages: [],
      isLoading: false,
      isTyping: false,
      previewImageUrl: null,
      showSystemEdit: false,
      isRichTextMode: false,
      saving: false,

      // 会话管理
      currentSession: null,
      sessions: [],

      // 角色管理
      userRoles: [],
      currentRole: null,
      editingRole: null,
      selectedTemplate: '',
      systemTemplates: [
        {
          key: 'assistant',
          name: '通用助手',
          content:
            '你是专业的AI助手，能够分析文本和图片，使用中文为用户提供准确有用的信息和建议。',
        },
        {
          key: 'analyst',
          name: '图片分析师',
          content:
            '你是专业的图片分析师，擅长从图片中找到各种线索，能够详细分析图片内容、推断场景、识别对象和关系。',
        },
        {
          key: 'programmer',
          name: '编程助手',
          content:
            '你是经验丰富的编程专家，熟悉多种编程语言和技术栈，能够帮助用户解决编程问题、优化代码、提供技术建议。',
        },
        {
          key: 'writer',
          name: '写作助手',
          content:
            '你是专业的写作助手，擅长各种文体创作，能够帮助用户改进文章结构、润色语言、提供创作灵感。',
        },
        {
          key: 'translator',
          name: '翻译专家',
          content:
            '你是专业的翻译专家，精通多种语言，能够提供准确、自然的翻译服务，并解释语言文化差异。',
        },
        {
          key: 'teacher',
          name: '学习导师',
          content:
            '你是耐心的学习导师，善于用简单易懂的方式解释复杂概念，能够根据学习者的水平调整教学方式。',
        },
      ],

      toast: {
        show: false,
        message: '',
        type: 'info',
        timeout: null,
      },
    }
  },
  computed: {
    canSend() {
      return (
        !this.isLoading &&
        (this.currentMessage.trim() || this.selectedImages.length > 0)
      )
    },
    currentSessionId: {
      get() {
        return this.currentSession ? this.currentSession.session_id : ''
      },
      set(sessionId) {
        this.switchToSession(sessionId)
      },
    },
    hasRoleChanges() {
      if (!this.currentRole || !this.editingRole) {
        return false
      }

      return (
        this.currentRole.name !== this.editingRole.name ||
        this.currentRole.system_prompt !== this.editingRole.system_prompt ||
        this.currentRole.description !== this.editingRole.description ||
        this.currentRole.is_default !== this.editingRole.is_default
      )
    },
  },
  mounted() {
    this.initializeChat()
  },
  methods: {
    async initializeChat() {
      try {
        await this.loadUserRoles()
        await this.loadSessions()

        // 尝试从本地存储中恢复上次使用的会话
        const lastSessionId = this.getLastSessionId()
        let sessionToLoad = null

        if (lastSessionId && this.sessions.length > 0) {
          sessionToLoad = this.sessions.find(
            (s) => s.session_id === lastSessionId,
          )
        }

        if (sessionToLoad) {
          this.currentSession = sessionToLoad
          await this.loadSessionMessages()
          console.log('已恢复上次使用的会话:', sessionToLoad.title)
        } else if (this.sessions.length === 0) {
          await this.createNewSession()
        } else {
          this.currentSession = this.sessions[0]
          await this.loadSessionMessages()
        }

        // 保存当前会话ID
        this.saveLastSessionId(this.currentSession?.session_id)
      } catch (error) {
        console.error('初始化聊天失败:', error)
        this.$message.error('初始化聊天失败')
      }
    },

    async loadUserRoles() {
      try {
        const response = await request.get('/chat/roles')
        if (response && response.success) {
          this.userRoles = response.data
          this.currentRole =
            this.userRoles.find((role) => role.is_default) || this.userRoles[0]

          if (this.userRoles.length === 0) {
            await this.createDefaultRole()
          }
        }
      } catch (error) {
        console.error('加载用户角色失败:', error)
        await this.createDefaultRole()
      }
    },

    async createDefaultRole() {
      try {
        const response = await request.post('/chat/roles', {
          name: '通用助手',
          system_prompt:
            '你是专业的AI助手，能够分析文本和图片，使用中文为用户提供准确有用的信息和建议。',
          description: '通用AI助手',
          is_default: true,
        })

        if (response && response.success) {
          this.userRoles = [response.data]
          this.currentRole = response.data
        }
      } catch (error) {
        console.error('创建默认角色失败:', error)
      }
    },

    async loadSessions() {
      try {
        const response = await request.get('/chat/sessions')
        if (response && response.success) {
          this.sessions = response.data
        }
      } catch (error) {
        console.error('加载会话失败:', error)
      }
    },

    async createNewSession() {
      try {
        const now = new Date()
        const timeStr = now.toLocaleString('zh-CN', {
          month: '2-digit',
          day: '2-digit',
          hour: '2-digit',
          minute: '2-digit',
        })
        const title = `新对话 ${timeStr}`

        const requestData = {
          title: title,
          model: 'vertexai##gemini-2.0-flash',
        }

        if (this.currentRole) {
          requestData.user_role_id = this.currentRole.id
        }

        const response = await request.post('/chat/sessions', requestData)
        if (response && response.success) {
          this.currentSession = response.data
          this.sessions.unshift(this.currentSession)
          this.messages = []

          // 保存新会话ID到本地存储
          this.saveLastSessionId(this.currentSession.session_id)

          this.$nextTick(() => {
            this.scrollToBottom()
          })
        }
      } catch (error) {
        console.error('创建会话失败:', error)
        throw error
      }
    },

    async loadSessionMessages() {
      if (!this.currentSession) return

      try {
        const response = await request.get(
          `/chat/sessions/${this.currentSession.session_id}`,
        )
        if (response && response.success) {
          const sessionData = response.data

          this.messages = sessionData.messages.map((msg) => {
            const messageData = {
              id: msg.id,
              role: msg.role,
              timestamp: new Date(msg.timestamp).getTime(),
              content: msg.content,
            }

            if (
              msg.multi_content &&
              Array.isArray(msg.multi_content) &&
              msg.multi_content.length > 0
            ) {
              messageData.type = 'multimodal'

              const textContent = this.extractTextFromMultiContent(
                msg.multi_content,
              )
              messageData.text = textContent || msg.content || ''

              messageData.images = this.extractImagesFromMultiContent(
                msg.multi_content,
              )
            } else {
              messageData.type = 'text'
              messageData.text = msg.content || ''
              messageData.images = []
            }

            return messageData
          })
          for (let index = 0; index < this.messages.length; index++) {
            const element = this.messages[index]
            for (let index = 0; index < element.images.length; index++) {
              const element2 = element.images[index]

              this.image_urls.push(element2.url)
            }
          }
          this.$nextTick(() => {
            this.scrollToBottom()
          })
        }
      } catch (error) {
        console.error('加载会话消息失败:', error)
      }
    },

    extractTextFromMultiContent(multiContent) {
      if (!multiContent || !Array.isArray(multiContent)) return ''

      const textItems = multiContent.filter(
        (item) =>
          item.mime_type === 'text' ||
          (item.text && typeof item.text === 'string'),
      )

      if (textItems.length > 0) {
        return textItems
          .map((item) => item.text || item.content || '')
          .join('\n')
      }

      return ''
    },

    extractImagesFromMultiContent(multiContent) {
      if (!multiContent || !Array.isArray(multiContent)) return []

      return multiContent
        .filter((item) => item.mime_type && item.mime_type.startsWith('image/'))
        .map((item, index) => ({
          url: `data:${item.mime_type};base64,${item.content}`,
          base64: item.content,
          mimeType: item.mime_type,
          name: `image_${index + 1}`,
        }))
    },

    async sendMessage() {
      if (!this.canSend) return

      if (!this.currentSession) {
        await this.createNewSession()
      }

      const messageContent = this.currentMessage.trim()
      const images = [...this.selectedImages]

      const userMessage = {
        id: `temp_${Date.now()}`,
        role: 'user',
        timestamp: Date.now(),
        type: images.length > 0 ? 'multimodal' : 'text',
        content: messageContent,
        text: messageContent,
        images: images,
      }

      this.messages.push(userMessage)
      this.currentMessage = ''
      this.selectedImages = []

      this.$nextTick(() => {
        this.scrollToBottom()
      })

      this.isLoading = true
      this.isTyping = true

      try {
        let requestData = {}

        if (images.length > 0) {
          const multiContent = []

          if (messageContent) {
            multiContent.push({
              mime_type: 'text',
              text: messageContent,
            })
          }

          for (const image of images) {
            multiContent.push({
              mime_type: image.mimeType || 'image/jpeg',
              content: image.base64,
            })
          }

          requestData = { multi_content: multiContent }
        } else {
          requestData = { content: messageContent }
        }

        const response = await request.post(
          `/chat/sessions/${this.currentSession.session_id}/messages`,
          requestData,
          {
            timeout: 30000,
          },
        )

        if (response && response.success && response.data) {
          const userMessageIndex = this.messages.findIndex(
            (msg) => msg.id === userMessage.id,
          )
          if (userMessageIndex !== -1) {
            this.messages[userMessageIndex].id = response.data.user_message.id
            this.messages[userMessageIndex].timestamp = new Date(
              response.data.user_message.timestamp,
            ).getTime()
          }

          const assistantMsgData = response.data.assistant_message
          const assistantMessage = {
            id: assistantMsgData.id,
            role: 'assistant',
            timestamp: new Date(assistantMsgData.timestamp).getTime(),
            content: assistantMsgData.content,
          }

          if (
            assistantMsgData.multi_content &&
            Array.isArray(assistantMsgData.multi_content) &&
            assistantMsgData.multi_content.length > 0
          ) {
            assistantMessage.type = 'multimodal'
            assistantMessage.text =
              this.extractTextFromMultiContent(
                assistantMsgData.multi_content,
              ) ||
              assistantMsgData.content ||
              ''
            assistantMessage.images = this.extractImagesFromMultiContent(
              assistantMsgData.multi_content,
            )
          } else {
            assistantMessage.type = 'text'
            assistantMessage.text = assistantMsgData.content || ''
            assistantMessage.images = []
          }

          this.messages.push(assistantMessage)

          this.$nextTick(() => {
            this.scrollToBottom()
          })
        } else {
          throw new Error(response?.message || '响应格式错误')
        }
      } catch (error) {
        console.error('发送消息失败:', error)
        this.$message.error('发送消息失败: ' + (error.message || '未知错误'))

        const errorMessage = {
          id: `error_${Date.now()}`,
          role: 'assistant',
          timestamp: Date.now(),
          type: 'text',
          content: '抱歉，我暂时无法回复您的消息。请稍后再试。',
        }

        this.messages.push(errorMessage)
      } finally {
        this.isLoading = false
        this.isTyping = false
        this.$nextTick(() => {
          this.scrollToBottom()
        })
      }
    },

    handleEnterKey(event) {
      if (event.shiftKey) {
        return
      } else {
        event.preventDefault()
        this.sendMessage()
      }
    },

    adjustTextareaHeight() {
      // Element Plus的textarea会自动调整高度
    },

    triggerImageUpload() {
      this.$refs.imageInput.click()
    },

    async handleImageUpload(event) {
      const files = Array.from(event.target.files)

      for (const file of files) {
        if (file.size > 10 * 1024 * 1024) {
          this.$message.error(`图片 ${file.name} 超过10MB限制`)
          continue
        }

        try {
          const imageData = await this.processImage(file)
          this.selectedImages.push(imageData)
        } catch (error) {
          console.error('处理图片失败:', error)
          this.$message.error(error.toString())
        }
      }

      event.target.value = ''
    },

    async processImage(file) {
      try {
        this.$message.info({
          message: `正在上传图片 ${file.name}...`,
          duration: 0,
          showClose: false,
        })

        const formData = new FormData()
        formData.append('image', file)

        const response = await request.post('/chat/upload-image', formData, {
          headers: {
            'Content-Type': 'multipart/form-data',
          },
        })

        if (response && response.success && response.data) {
          // 关闭之前的上传提示
          this.$message.closeAll()
          return {
            name: response.data.filename,
            url: `data:${response.data.mime_type};base64,${response.data.base64}`,
            base64: response.data.base64,
            mimeType: response.data.mime_type,
            size: response.data.size,
          }
        } else {
          throw new Error(response?.message || '图片上传失败')
        }
      } catch (error) {
        // 关闭之前的上传提示
        this.$message.closeAll()

        console.warn('服务端图片上传失败，使用本地处理:', error)
        // return this.processImageLocally(file)
        throw new Error(error || '图片上传失败')
      }
    },

    async processImageLocally(file) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.onload = (e) => {
          const img = new Image()
          img.onload = () => {
            const canvas = document.createElement('canvas')
            const ctx = canvas.getContext('2d')

            const maxWidth = 800
            const maxHeight = 800
            let { width, height } = img

            if (width > maxWidth || height > maxHeight) {
              const ratio = Math.min(maxWidth / width, maxHeight / height)
              width *= ratio
              height *= ratio
            }

            canvas.width = width
            canvas.height = height

            ctx.drawImage(img, 0, 0, width, height)

            const base64 = canvas.toDataURL('image/jpeg', 0.8)
            const base64Data = base64.split(',')[1]

            resolve({
              name: file.name,
              url: base64,
              base64: base64Data,
              mimeType: 'image/jpeg',
              size: file.size,
            })
          }
          img.onerror = reject
          img.src = e.target.result
        }
        reader.onerror = reject
        reader.readAsDataURL(file)
      })
    },

    removeImage(index) {
      this.selectedImages.splice(index, 1)
    },

    formatMessage(content) {
      if (!content) return ''
      try {
        return content
        // marked(content, {
        //   breaks: true,
        //   gfm: true,
        //   sanitize: false,
        //   smartLists: true,
        //   smartypants: true,
        // })
      } catch (error) {
        console.error('Markdown解析错误:', error)
        return content.replace(/\n/g, '<br>')
      }
    },

    formatTime(timestamp) {
      const date = new Date(timestamp)
      const now = new Date()
      const diff = now - date

      if (diff < 60000) {
        return '刚刚'
      } else if (diff < 3600000) {
        return `${Math.floor(diff / 60000)}分钟前`
      } else if (date.toDateString() === now.toDateString()) {
        return date.toLocaleTimeString('zh-CN', {
          hour: '2-digit',
          minute: '2-digit',
        })
      } else {
        return date.toLocaleString('zh-CN', {
          month: '2-digit',
          day: '2-digit',
          hour: '2-digit',
          minute: '2-digit',
        })
      }
    },

    scrollToBottom() {
      const container = this.$refs.messagesContainer
      if (container) {
        container.scrollTop = container.scrollHeight
      }
    },

    async deleteCurrentSession() {
      if (!this.currentSession) return

      try {
        await this.$confirm(
          `确定要删除会话"${this.currentSession.title}"吗？`,
          '确认删除',
          {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
          },
        )

        await request.delete(`/chat/sessions/${this.currentSession.session_id}`)

        const deletedSessionId = this.currentSession.session_id
        const index = this.sessions.findIndex(
          (s) => s.session_id === deletedSessionId,
        )
        if (index !== -1) {
          this.sessions.splice(index, 1)
        }

        // 如果删除的是当前存储的会话，清理本地存储
        if (this.getLastSessionId() === deletedSessionId) {
          this.saveLastSessionId(null)
        }

        if (this.sessions.length > 0) {
          this.currentSession = this.sessions[0]
          await this.loadSessionMessages()
          // 保存新的当前会话
          this.saveLastSessionId(this.currentSession.session_id)
          this.$message.success('会话已删除，已切换到最新会话')
        } else {
          await this.createNewSession()
          this.$message.success('会话已删除，已创建新会话')
        }
      } catch (error) {
        if (error !== 'cancel') {
          console.error('删除会话失败:', error)
          this.$message.error('删除会话失败: ' + (error.message || '未知错误'))
        }
      }
    },

    async startNewChat() {
      try {
        await this.createNewSession()
        this.$message.success('已开始新对话')
      } catch (error) {
        console.error('新开对话失败:', error)
        this.$message.error('新开对话失败')
      }
    },

    async switchToSession(sessionId) {
      try {
        const session = this.sessions.find((s) => s.session_id === sessionId)

        if (session && session.session_id !== this.currentSession?.session_id) {
          this.currentSession = session
          await this.loadSessionMessages()
          // 保存当前会话ID到本地存储
          this.saveLastSessionId(sessionId)
          this.$message.success(`已切换到：${session.title}`)
        }
      } catch (error) {
        console.error('切换会话失败:', error)
        this.$message.error('切换会话失败')
      }
    },

    exportChat() {
      const chatData = {
        exportTime: new Date().toLocaleString('zh-CN'),
        messages: this.messages.map((msg) => ({
          role: msg.role,
          type: msg.type,
          content: msg.content || msg.text,
          time: this.formatTime(msg.timestamp),
          hasImages: msg.images && msg.images.length > 0,
        })),
      }

      const dataStr = JSON.stringify(chatData, null, 2)
      const dataBlob = new Blob([dataStr], { type: 'application/json' })

      const link = document.createElement('a')
      link.href = URL.createObjectURL(dataBlob)
      link.download = `chat-export-${new Date().getTime()}.json`
      link.click()

      this.$message.success('对话已导出')
    },

    async toggleSystemEdit() {
      this.showSystemEdit = true

      if (this.showSystemEdit) {
        await this.loadUserRoles()

        if (!this.currentRole && this.userRoles.length > 0) {
          this.currentRole =
            this.userRoles.find((role) => role.is_default) || this.userRoles[0]
        }

        this.initEditingRole()
      }
    },

    applyTemplate() {
      if (this.selectedTemplate) {
        const template = this.systemTemplates.find(
          (t) => t.key === this.selectedTemplate,
        )
        if (template && this.editingRole) {
          this.editingRole.system_prompt = template.content
          this.$message.success(`已应用"${template.name}"模板`)
        }
      }
      this.selectedTemplate = ''
    },

    initEditingRole() {
      if (this.currentRole) {
        this.editingRole = {
          id: this.currentRole.id,
          name: this.currentRole.name,
          system_prompt: this.currentRole.system_prompt,
          description: this.currentRole.description || '',
          is_default: this.currentRole.is_default,
        }
      } else {
        this.editingRole = {
          id: null,
          name: '',
          system_prompt: '',
          description: '',
          is_default: false,
        }
      }
    },

    selectRole(role) {
      if (!role) return

      if (this.hasRoleChanges) {
        this.$confirm(
          '当前有未保存的修改，切换角色将丢失这些修改。确定要继续吗？',
          '确认切换',
          {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
          },
        )
          .then(() => {
            this.currentRole = role
            this.initEditingRole()
          })
          .catch(() => {})
        return
      }

      this.currentRole = role
      this.initEditingRole()
    },

    resetRoleEdit() {
      this.initEditingRole()
      this.$message.info('已重置修改')
    },

    closeRoleDialog() {
      if (this.hasRoleChanges) {
        this.$confirm('当前有未保存的修改，确定要关闭吗？', '确认关闭', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        })
          .then(() => {
            this.showSystemEdit = false
            this.resetRoleEdit()
          })
          .catch(() => {})
      } else {
        this.showSystemEdit = false
      }
    },

    async saveCurrentRole() {
      if (!this.editingRole || !this.editingRole.name?.trim()) {
        this.$message.warning('角色名称不能为空')
        return
      }

      this.saving = true
      try {
        if (this.editingRole.is_default && !this.currentRole.is_default) {
          for (const role of this.userRoles) {
            if (role.is_default && role.id !== this.currentRole.id) {
              await request.put(`/chat/roles/${role.id}`, {
                is_default: false,
              })
              role.is_default = false
            }
          }
        } else if (
          !this.editingRole.is_default &&
          this.currentRole.is_default
        ) {
          const otherRoles = this.userRoles.filter(
            (role) => role.id !== this.currentRole.id,
          )
          if (otherRoles.length > 0) {
            const newDefaultRole = otherRoles[0]
            await request.put(`/chat/roles/${newDefaultRole.id}`, {
              is_default: true,
            })
            newDefaultRole.is_default = true
            this.$message.info(`已选择使用"${newDefaultRole.name}"角色`)
          } else {
            this.editingRole.is_default = true
            this.$message.warning('至少需要选择一个角色')
            return
          }
        }

        const response = await request.put(
          `/chat/roles/${this.currentRole.id}`,
          {
            name: this.editingRole.name.trim(),
            system_prompt: this.editingRole.system_prompt,
            description: this.editingRole.description,
            is_default: this.editingRole.is_default,
          },
        )

        if (response && response.success) {
          this.currentRole.name = this.editingRole.name.trim()
          this.currentRole.system_prompt = this.editingRole.system_prompt
          this.currentRole.description = this.editingRole.description
          this.currentRole.is_default = this.editingRole.is_default

          const roleInList = this.userRoles.find(
            (role) => role.id === this.currentRole.id,
          )
          if (roleInList) {
            roleInList.name = this.editingRole.name.trim()
            roleInList.system_prompt = this.editingRole.system_prompt
            roleInList.description = this.editingRole.description
            roleInList.is_default = this.editingRole.is_default
          }

          this.$message.success('角色保存成功')
        }
      } catch (error) {
        console.error('保存角色失败:', error)
        if (error.response?.data?.error_code === '6002') {
          this.$message.error('角色名称已存在')
        } else {
          this.$message.error('保存角色失败')
        }
      } finally {
        this.saving = false
      }
    },

    truncateTitle(title, maxLength = 20) {
      if (!title) return ''
      return title.length > maxLength
        ? title.substring(0, maxLength) + '...'
        : title
    },

    toggleRichTextMode() {
      this.isRichTextMode = !this.isRichTextMode
    },

    insertFormat(before, after) {
      const textarea = this.$refs.messageInput.$refs.textarea
      if (!textarea) return

      const start = textarea.selectionStart
      const end = textarea.selectionEnd
      const selectedText = this.currentMessage.substring(start, end)

      const beforeText = this.currentMessage.substring(0, start)
      const afterText = this.currentMessage.substring(end)

      this.currentMessage =
        beforeText + before + selectedText + after + afterText

      this.$nextTick(() => {
        textarea.focus()
        const newStart = start + before.length
        const newEnd = newStart + selectedText.length
        textarea.setSelectionRange(newStart, newEnd)
      })
    },

    // 本地存储方法
    getLastSessionId() {
      try {
        return localStorage.getItem('chatv2_last_session_id')
      } catch (error) {
        console.warn('读取本地存储失败:', error)
        return null
      }
    },

    saveLastSessionId(sessionId) {
      try {
        if (sessionId) {
          localStorage.setItem('chatv2_last_session_id', sessionId)
        } else {
          localStorage.removeItem('chatv2_last_session_id')
        }
      } catch (error) {
        console.warn('保存本地存储失败:', error)
      }
    },
  },
}
</script>

<style scoped>
.chat-container {
  padding: 20px;
  max-width: 100%;
  margin: 0;
  width: 100%;
  /* background: #ffffff; */
  height: calc(100vh - 74px);
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow: hidden; /* 防止整个页面滚动 */
}

/* 页面头部 */
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  flex-shrink: 0;
}

.page-header h3 {
  margin: 0;
  color: #303133;
  font-size: 22px;
  font-weight: 600;
}

.session-info {
  font-size: 14px;
  color: #606266;
  font-weight: 400;
  margin-left: 8px;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

/* 角色管理悬浮框 */
.role-dialog .el-dialog {
  border-radius: 8px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
}

.role-dialog .el-dialog__header {
  border-bottom: 1px solid var(--el-border-color);
  padding: 16px 24px;
}

.role-dialog .el-dialog__title {
  font-size: 18px;
  font-weight: 600;
  color: #303133;
}

.role-dialog .el-dialog__body {
  padding: 20px 24px;
  max-height: 60vh;
  overflow-y: auto;
}

.role-dialog .el-dialog__footer {
  border-top: 1px solid var(--el-border-color);
  padding: 16px 24px;
}

.dialog-footer {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

.role-selection {
  margin-bottom: 24px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--el-border-color);
}

.role-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

.role-tag {
  cursor: pointer;
  transition: all 0.2s;
  border-radius: 6px;
}

.role-tag:hover {
  transform: scale(1.05);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.role-edit {
  margin-top: 0;
}

.role-checkbox {
  margin-top: 8px;
}

.template-header {
  margin-bottom: 8px;
}

/* 消息卡片 */
.messages-card {
  flex: 1;
  display: flex !important;
  flex-direction: column !important;
  min-height: 0;
  border-radius: 6px;
  border: 1px solid var(--el-border-color);
  overflow: hidden;
}

/* 覆盖el-card的默认样式 */
.messages-card :deep(.el-card__body) {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 0 !important;
  overflow: hidden;
  height: 100%;
  box-sizing: border-box;
}

.messages-container {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-height: 0;
  height: 100%;
  box-sizing: border-box;
}

/* 欢迎消息 */
.welcome-message {
  text-align: center;
  padding: 60px 20px;
  color: #606266;
}

.welcome-icon {
  margin-bottom: 16px;
}

.welcome-text {
  font-size: 18px;
  margin-bottom: 8px;
  color: #606266;
}

.welcome-desc {
  font-size: 14px;
  color: #909399;
}

/* 消息项 */
.message-item {
  display: flex;
  gap: 12px;
  max-width: 80%;
  align-self: flex-start;
}

.message-item.user {
  align-self: flex-end;
  flex-direction: row-reverse;
}

.message-item.user .message-content {
  text-align: right;
}

.message-item.assistant {
  align-self: flex-start;
}

.message-avatar {
  flex-shrink: 0;
}

.message-content {
  flex: 1;
  min-width: 0;
}

.message-time {
  font-size: 12px;
  color: #c0c4cc;
  margin-bottom: 4px;
}

.user .message-time {
  text-align: right;
}

.message-text {
  /* background: #f0f0f0; */
  padding: 12px 16px;
  border-radius: 18px;
  word-wrap: break-word;
  line-height: 1.5;
  text-align: left;
}

.user .message-text {
  background: #409eff;
  color: white;
}

/* Markdown样式 */
.message-text :deep(h1),
.message-text :deep(h2),
.message-text :deep(h3),
.message-text :deep(h4),
.message-text :deep(h5),
.message-text :deep(h6) {
  margin: 0.5em 0;
  font-weight: 600;
}

.message-text :deep(p) {
  margin: 0.5em 0;
}

.message-text :deep(p:first-child) {
  margin-top: 0;
}

.message-text :deep(p:last-child) {
  margin-bottom: 0;
}

.message-text :deep(ul),
.message-text :deep(ol) {
  margin: 0.5em 0;
  padding-left: 1.5em;
}

.message-text :deep(li) {
  margin: 0.2em 0;
}

.message-text :deep(code) {
  background: rgba(0, 0, 0, 0.1);
  padding: 2px 4px;
  border-radius: 3px;
  font-family: 'Courier New', Monaco, monospace;
  font-size: 0.9em;
}

.user .message-text :deep(code) {
  background: rgba(255, 255, 255, 0.2);
}

.message-text :deep(pre) {
  background: rgba(0, 0, 0, 0.05);
  padding: 12px;
  border-radius: 6px;
  overflow-x: auto;
  margin: 0.5em 0;
}

.user .message-text :deep(pre) {
  background: rgba(255, 255, 255, 0.1);
}

.message-text :deep(blockquote) {
  margin: 0.5em 0;
  padding: 0.5em 1em;
  border-left: 4px solid #ddd;
  background: rgba(0, 0, 0, 0.02);
  font-style: italic;
}

.user .message-text :deep(blockquote) {
  border-left-color: rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.1);
}

/* 多模态消息 */
.message-multimodal {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.message-images {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.message-item.user .message-images {
  justify-content: flex-end;
}

.message-image {
  max-width: 200px;
  max-height: 200px;
  border-radius: 8px;
  cursor: pointer;
  transition: transform 0.2s;
}

.message-image:hover {
  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}

/* 正在输入指示器 */
.typing-indicator {
  display: flex;
  gap: 4px;
  padding: 16px;
}

.typing-indicator span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  /* background: #c0c4cc; */
  animation: typing 1.4s infinite ease-in-out;
}

.typing-indicator span:nth-child(1) {
  animation-delay: -0.32s;
}
.typing-indicator span:nth-child(2) {
  animation-delay: -0.16s;
}

@keyframes typing {
  0%,
  80%,
  100% {
    transform: scale(0);
  }
  40% {
    transform: scale(1);
  }
}

/* 输入卡片 */
.input-card {
  flex-shrink: 0;
  border-radius: 6px;
  border: 1px solid var(--el-border-color);
}

/* 图片预览 */
.image-preview-container {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}

.image-preview-item {
  position: relative;
  width: 60px;
  height: 60px;
}

.preview-image {
  width: 100%;
  height: 100%;
  border-radius: 6px;
}

.remove-image-btn {
  position: absolute;
  top: -6px;
  right: -6px;
  z-index: 1;
}

/* 富文本工具栏 */
.toolbar {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
  padding: 10px 14px;
  /* background: white; */
  border-radius: 6px;
  border: 1px solid var(--el-border-color);
  flex-shrink: 0;
}

/* 输入框包装器 */
.input-wrapper {
  position: relative;
}

.input-controls {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 12px;
}

.left-controls,
.right-controls {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* 响应式样式 */
@media (max-width: 768px) {
  .chat-container {
    padding: 16px;
    height: calc(100vh - 60px);
  }

  .message-item {
    max-width: 95%;
  }

  .page-header h3 {
    font-size: 20px;
  }

  .page-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }

  .header-actions {
    width: 100%;
    justify-content: flex-end;
  }

  .role-tabs {
    flex-direction: column;
  }

  .role-dialog .el-dialog {
    width: 90% !important;
    max-width: 500px;
    margin: 20px auto;
  }

  .role-dialog .el-dialog__body {
    max-height: 50vh;
    padding: 16px 20px;
  }

  .role-dialog .el-dialog__header {
    padding: 12px 20px;
  }

  .role-dialog .el-dialog__footer {
    padding: 12px 20px;
  }
}

/* 滚动条样式 */
.messages-container::-webkit-scrollbar {
  width: 6px;
}

.messages-container::-webkit-scrollbar-track {
  /* background: #f1f1f1;   */
  border-radius: 3px;
}

.messages-container::-webkit-scrollbar-thumb {
  /* background: #c1c1c1; */
  border-radius: 3px;
}

.messages-container::-webkit-scrollbar-thumb:hover {
  /* background: #a8a8a8; */
}
</style>